
#include <stdio.h>
#include "driver/i2c.h"
#include "hal_i2c.h"

#define IIC_TIME_OUT (10000 / portTICK_RATE_MS)

#define I2C_MASTER_TX_BUF_DISABLE 0 /*!< I2C master doesn't need buffer */
#define I2C_MASTER_RX_BUF_DISABLE 0 /*!< I2C master doesn't need buffer */
#define WRITE_BIT I2C_MASTER_WRITE  /*!< I2C master write */
#define READ_BIT I2C_MASTER_READ    /*!< I2C master read */
#define ACK_CHECK_EN 0x1            /*!< I2C master will check ack from slave*/
#define ACK_CHECK_DIS 0x0           /*!< I2C master will not check ack from slave */
#define ACK_VAL 0x0                 /*!< I2C ack value */
#define NACK_VAL 0x1                /*!< I2C nack value */



int i2c_init()
{
    i2c_config_t conf = {
        .mode = I2C_MODE_MASTER,
        .sda_io_num = IIC_SDA_PIN_NUM,
        //.sda_pullup_en = GPIO_PULLUP_ENABLE,
        .scl_io_num = IIC_SCL_PIN_NUM,
        //.scl_pullup_en = GPIO_PULLUP_ENABLE,
        .master.clk_speed = IIC_USER_FREQUENCE
    };
    i2c_param_config(IIC_USER_NUM, &conf);
    i2c_driver_install(IIC_USER_NUM, conf.mode, I2C_MASTER_RX_BUF_DISABLE, I2C_MASTER_TX_BUF_DISABLE, 0);
    return 0;
}


int i2c_write_mem(char addr,void *mem,int mem_size,void *data,int data_size)
{
    i2c_cmd_handle_t cmd = i2c_cmd_link_create();
    i2c_master_start(cmd);
    i2c_master_write_byte(cmd, addr << 1 | WRITE_BIT, ACK_CHECK_EN);
    i2c_master_write(cmd, mem, mem_size, ACK_CHECK_EN);
    i2c_master_write(cmd, data, data_size, ACK_CHECK_EN);
    i2c_master_stop(cmd);
    esp_err_t ret = i2c_master_cmd_begin(IIC_USER_NUM, cmd, IIC_TIME_OUT);
    i2c_cmd_link_delete(cmd);
    return ret;
}

int i2c_read_mem(char addr,void *mem,int mem_size,void *data,int data_size)
{
    i2c_cmd_handle_t cmd = i2c_cmd_link_create();
    i2c_master_start(cmd);
   
    i2c_master_write_byte(cmd, addr << 1 | WRITE_BIT, ACK_CHECK_EN);
    i2c_master_write(cmd, mem, mem_size, ACK_CHECK_EN);
    i2c_master_start(cmd);
    
    i2c_master_write_byte(cmd, addr << 1 | READ_BIT, ACK_CHECK_EN);
     if (data_size > 1)
    {
        i2c_master_read(cmd, data, data_size - 1, ACK_VAL);
    }
    i2c_master_read_byte(cmd, data + data_size - 1, NACK_VAL);
    i2c_master_stop(cmd);
    esp_err_t ret = i2c_master_cmd_begin(IIC_USER_NUM, cmd,IIC_TIME_OUT);
    i2c_cmd_link_delete(cmd);
    return ret;
}


int i2c_write(char addr,void *data,int data_size)
{
    i2c_cmd_handle_t cmd = i2c_cmd_link_create();
    i2c_master_start(cmd);
    i2c_master_write_byte(cmd, addr << 1 | WRITE_BIT, ACK_CHECK_EN);
    i2c_master_write(cmd, data, data_size, ACK_CHECK_EN);
    i2c_master_stop(cmd);
    esp_err_t ret = i2c_master_cmd_begin(IIC_USER_NUM, cmd, IIC_TIME_OUT);
    i2c_cmd_link_delete(cmd);
    return ret;
}

int i2c_read(char addr,void *data,int data_size)
{
    i2c_cmd_handle_t cmd = i2c_cmd_link_create();
    i2c_master_start(cmd);
   
    i2c_master_write_byte(cmd, addr << 1 | READ_BIT, ACK_CHECK_EN);
    
    if (data_size > 1)
    {
        i2c_master_read(cmd, data, data_size - 1, ACK_VAL);
    }
    i2c_master_read_byte(cmd, data + data_size - 1, NACK_VAL);
    i2c_master_stop(cmd);
    esp_err_t ret = i2c_master_cmd_begin(IIC_USER_NUM, cmd,IIC_TIME_OUT);
    i2c_cmd_link_delete(cmd);
    return ret;
}

